import type { ChatBroResponseType, MessageType } from "~/types/chat";
import type { PageParamsType } from "~/types/global";

// event scanner
class EventScanner<T = any> {
    readonly words: Array<T> = [];
    readonly delay: number;
    readonly onScan: (data: T) => boolean;
    #finished = false;

    constructor(delay: number, onScan: (data: T) => boolean) {
        this.delay = delay;
        this.onScan = onScan;
    }

    async start() {
        while (!this.#finished) {
            const stop = await new Promise<boolean>(resolve => {
                setTimeout(() => {
                    const data = this.words.shift();
                    if (data) this.onScan(data);
                    resolve(false);
                }, this.delay);
            });
            if (stop) break;
        }
        this.#finished = true;
    }

    push(data: T) {
        this.words.push(data);
    }

    stop() {
        this.#finished = true;
    }
}

export default () => {
    const { createEventSourceFetch, createHttpFetch } = useHttpRequest();

    // send a message in a session
    const sendMsg = (msg: string, session_id: string, onopen: () => void, onmessage: (msg: string) => void) => {
        return new Promise<void>((resolve, reject) => {
            // create scanner
            const scanner = new EventScanner(100, data => {
                if (data !== '[DONE]') {
                    onmessage(JSON.parse(data));
                    return false;
                }
                // end
                resolve();
                return true;
            });
            createEventSourceFetch('/api/chat', {
                method: 'POST',
                body: JSON.stringify({ msg, session_id }),
                async onopen() {
                    onopen();
                    scanner.start();
                },
                onmessage(e) {
                    scanner.push(e.data);
                },
            }).catch(err => {
                scanner.stop();
                reject(err);
            });
        });
    };

    // create a session with ( or not ) a template id
    const createSession = (template_id?: string) => {
        return createHttpFetch('/api/session', {
            method: 'POST',
            body: { template_id },
        });
    };

    // research all sessions
    const getSessionList = (pageParams: PageParamsType) => {
        return createHttpFetch('/api/session', {
            method: 'GET',
            query: pageParams,
        });
    };

    // select message list by session id
    const getMsgListBySessionId = (session_id: string) => {
        return createHttpFetch<{ list: MessageType[] }>('/api/chat', {
            method: 'GET',
            query: { session_id },
        });
    };

    return { sendMsg, createSession, getSessionList, getMsgListBySessionId };
};